/*
 * Copyright (C) 2010 mAPPn.Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mlizhi.base;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LayoutAnimationController;
import android.view.animation.TranslateAnimation;

/**
 * Common Utils for the application
 * 
 * @author TroyLi
 */
public class Utils {

	public static boolean sDebug;
	public static String sLogTag;
	
	
	


	// UTF-8 encoding
	private static final String ENCODING_UTF8 = "UTF-8";

	/**
	 * <p>
	 * Get UTF8 bytes from a string
	 * </p>
	 * 
	 * @param string
	 *String
	 * @return UTF8 byte array, or null if failed to get UTF8 byte array
	 */
	public static byte[] getUTF8Bytes(String string) {
		if (string == null)
			return new byte[0];

		try {
			return string.getBytes(ENCODING_UTF8);
		} catch (UnsupportedEncodingException e) {
			/*
			 * If system doesn't support UTF-8, use another way
			 */
			try {
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				DataOutputStream dos = new DataOutputStream(bos);
				dos.writeUTF(string);
				byte[] jdata = bos.toByteArray();
				bos.close();
				dos.close();
				byte[] buff = new byte[jdata.length - 2];
				System.arraycopy(jdata, 2, buff, 0, buff.length);
				return buff;
			} catch (IOException ex) {
				return new byte[0];
			}
		}
	}

	/**
	 * <p>
	 * Get string in UTF-8 encoding
	 * </p>
	 * 
	 * @param b
	 *byte array
	 * @return string in utf-8 encoding, or empty if the byte array is not
	 * encoded with UTF-8
	 */
	public static String getUTF8String(byte[] b) {
		if (b == null)
			return "";
		return getUTF8String(b, 0, b.length);
	}

	/**
	 * <p>
	 * Get string in UTF-8 encoding
	 * </p>
	 */
	public static String getUTF8String(byte[] b, int start, int length) {
		if (b == null) {
			return "";
		} else {
			try {
				return new String(b, start, length, ENCODING_UTF8);
			} catch (UnsupportedEncodingException e) {
				return "";
			}
		}
	}

	/**
	 * <p>
	 * Parse int value from string
	 * </p>
	 * 
	 * @param value
	 *string
	 * @return int value
	 */
	public static int getInt(String value) {
		if (TextUtils.isEmpty(value)) {
			return 0;
		}

		try {
			return Integer.parseInt(value.trim(), 10);
		} catch (NumberFormatException e) {
			return 0;
		}
	}

	/**
	 * <p>
	 * Parse float value from string
	 * </p>
	 * 
	 * @param value
	 *string
	 * @return float value
	 */
	public static float getFloat(String value) {
		if (value == null)
			return 0f;

		try {
			return Float.parseFloat(value.trim());
		} catch (NumberFormatException e) {
			return 0f;
		}
	}

	/**
	 * <p>
	 * Parse long value from string
	 * </p>
	 * 
	 * @param value
	 *string
	 * @return long value
	 */
	public static long getLong(String value) {
		if (value == null)
			return 0L;

		try {
			return Long.parseLong(value.trim());
		} catch (NumberFormatException e) {
			return 0L;
		}
	}

	public static void V(String msg) {
		if (sDebug) {
			Log.v(sLogTag, msg);
		}
	}

	public static void V(String msg, Throwable e) {
		if (sDebug) {
			Log.v(sLogTag, msg, e);
		}
	}

	public static void D(String msg) {
		if (sDebug) {
			Log.d(sLogTag, msg);
		}
	}

	public static void D(String msg, Throwable e) {
		if (sDebug) {
			Log.d(sLogTag, msg, e);
		}
	}

	public static void I(String msg) {
		if (sDebug) {
			Log.i(sLogTag, msg);
		}
	}

	public static void I(String msg, Throwable e) {
		if (sDebug) {
			Log.i(sLogTag, msg, e);
		}
	}

	public static void W(String msg) {
		if (sDebug) {
			Log.w(sLogTag, msg);
		}
	}

	public static void W(String msg, Throwable e) {
		if (sDebug) {
			Log.w(sLogTag, msg, e);
		}
	}

	public static void E(String msg) {
		if (sDebug) {
			Log.e(sLogTag, msg);
		}
	}

	public static void E(String msg, Throwable e) {
		if (sDebug) {
			Log.e(sLogTag, msg, e);
		}
	}


	



	/**
	 * 界面切换动画
	 * 
	 * @return
	 */
	public static LayoutAnimationController getLayoutAnimation() {
		AnimationSet set = new AnimationSet(true);

		Animation animation = new AlphaAnimation(0.0f, 1.0f);
		animation.setDuration(50);
		set.addAnimation(animation);

		animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
				Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
				-1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
		animation.setDuration(100);
		set.addAnimation(animation);

		LayoutAnimationController controller = new LayoutAnimationController(
				set, 0.5f);
		return controller;
	}



	/**
	 * Get MD5 Code
	 */
	public static String getMD5(String text) {
		try {
			byte[] byteArray = text.getBytes("utf8");
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(byteArray, 0, byteArray.length);
			return convertToHex(md.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return "";
	}

	/**
	 * 将字节转换为16进制
	 */
	private static String convertToHex(byte[] data) {
		StringBuilder buf = new StringBuilder();
		for (int i = 0; i < data.length; i++) {
			int halfbyte = (data[i] >>> 4) & 0x0F;
			int two_halfs = 0;
			do {
				if ((0 <= halfbyte) && (halfbyte <= 9))
					buf.append((char) ('0' + halfbyte));
				else
					buf.append((char) ('a' + (halfbyte - 10)));
				halfbyte = data[i] & 0x0F;
			} while (two_halfs++ < 1);
		}
		return buf.toString();
	}

	/**
	 * 检测本机的SD卡是否可读
	 */
	public static boolean isSdcardReadable() {
		final String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)
				|| Environment.MEDIA_MOUNTED.equals(state)) {
			return true;
		}
		return false;
	}

	/**
	 * 检测本机的SD卡是否可写
	 */
	public static boolean isSdcardWritable() {
		final String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)) {
			return true;
		}
		return false;
	}




	/**
	 * 检查是否应该进行更新
	 */
	public static boolean isNeedCheckUpgrade(Context context) {
		long currentTime = System.currentTimeMillis();
		long lastCheckTime = Session.get(context).getUpdataCheckTime();
		if (currentTime - lastCheckTime > 86400000) {
			// we only check update every 24 hours
			return true;
		}
		return false;
	}

	/**
	 * 清理缓存
	 * 
	 * @param context
	 */
	public static void clearCache(Context context) {
		File file = Environment.getDownloadCacheDirectory();
		File[] files = file.listFiles();
		if (files != null) {
			for (File f : files) {
				f.delete();
			}
		}
		file = context.getCacheDir();
		files = file.listFiles();
		if (files != null) {
			for (File f : files) {
				f.delete();
			}
		}
	}

	public static int dip2px(Context context, float dpValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (dpValue * scale + 0.5f);
	}

	public static int px2dip(Context context, float pxValue) {
		final float scale = context.getResources().getDisplayMetrics().density;
		return (int) (pxValue / scale + 0.5f);
	}
	
	public static int getScreenWidth(Context context)
	{
		WindowManager manager = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		Display display = manager.getDefaultDisplay();
		return display.getWidth();
	}

	public static int getScreenHeight(Context context)
	{
		WindowManager manager = (WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE);
		Display display = manager.getDefaultDisplay();
		return display.getHeight();
	}
	
	
}